Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for OpenXR local floor extension #87235

Merged
merged 1 commit into from
Jan 24, 2024

Conversation

dsnopek
Copy link
Contributor

@dsnopek dsnopek commented Jan 15, 2024

This adds support for the OpenXR local floor extension:

https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_local_floor

And allows the user to select it as their reference space.

Something that isn't ideal: if the developer picks "Local Floor", and it isn't supported, it'll probably fallback on the "Local" reference space, where I'd expect most developers to actually want "Stage" as the fallback. Should we try adding a more controlled fallback system in this PR? Or, save that for a follow-up?

UPDATE: This PR will now use the method of emulating LOCAL_FLOOR (if it's not supported) using STAGE and LOCAL that is described in the OpenXR spec at the end of this section.

This works in my testing on a Meta Quest 3.

@dsnopek dsnopek added this to the 4.x milestone Jan 15, 2024
@dsnopek dsnopek requested review from a team as code owners January 15, 2024 22:31
Copy link
Contributor

@m4gr3d m4gr3d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good and I tested and it works as expected!

For the fallback, the spec recommends an alternative application specific space in https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_local_floor. I'd suggest we use that instead and add it to this PR.

@m4gr3d m4gr3d modified the milestones: 4.x, 4.3 Jan 17, 2024
@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 17, 2024

@m4gr3d:

For the fallback, the spec recommends an alternative application specific space in https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_local_floor. I'd suggest we use that instead and add it to this PR.

Are you referring to the note below?

"Note: The LOCAL_FLOOR space could be implemented by an application without support from the runtime by using the difference between in the Y coordinate of the pose of the LOCAL and STAGE reference spaces."

EDIT: Oh, and I see the code sample a little further down in the spec as well. I'll see how we can integrate that!

@m4gr3d
Copy link
Contributor

m4gr3d commented Jan 17, 2024

@m4gr3d:

For the fallback, the spec recommends an alternative application specific space in https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_local_floor. I'd suggest we use that instead and add it to this PR.

Are you referring to the note below?

"Note: The LOCAL_FLOOR space could be implemented by an application without support from the runtime by using the difference between in the Y coordinate of the pose of the LOCAL and STAGE reference spaces."

Yeah, that's the one I was referring to.

@dsnopek dsnopek marked this pull request as draft January 17, 2024 14:44
@dsnopek dsnopek force-pushed the openxr-local-floor branch from db440aa to 13cbab6 Compare January 17, 2024 20:51
@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 17, 2024

I've hit a little bit of a snag in implementing the example code to emulate LOCAL_FLOOR using LOCAL and STAGE: in order to get the Y position of the stage space, we need to call xrLocateSpace() which requires a time. However, at the point where we're creating the reference space, it's still part of our initialization, and we haven't called xrWaitFrame() yet, so we don't know what the time should be. I tried using a number of arbitrary small values in my testing, but I can never get any position other than (0, 0, 0).

I think the solution is just to defer doing this until after the first xrWaitFrame(), which I'll try in a moment. But I wanted to push the current pretty code before I make a mess of it :-)

@dsnopek dsnopek force-pushed the openxr-local-floor branch from 13cbab6 to c76bd93 Compare January 17, 2024 21:17
@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 17, 2024

Nevermind! It looks like I was making a very small and very dumb mistake - the emulation code code does, in fact, work during initialization when using the arbitrary time value of 1 (since 0 is always invalid).

However, it may still make sense to refactor it so we can re-setup the reference space with a new floor height from STAGE, since, as it is, it will only set the floor height the one time. If later the OpenXR runtime has a new floor height, we want to be able to use that, although, I'm not sure what would tell us that a new floor height is available?

@dsnopek dsnopek force-pushed the openxr-local-floor branch from c76bd93 to 4bade79 Compare January 17, 2024 22:06
@dsnopek dsnopek marked this pull request as ready for review January 17, 2024 22:14
@dsnopek dsnopek requested a review from m4gr3d January 17, 2024 22:14
@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 17, 2024

Alright! I've refactored this so that (a) we can reset the floor height when using the emulated LOCAL_FLOOR (although, currently, this is only triggered at startup) and (b) we do this resetting after xrWaitFrame() so we can use a real time value.

I've tested all the different branches (including real LOCAL_FLOOR, emulated LOCAL_FLOOR and where we just fallback on a guessed floor height) by selectively commenting stuff out. It seems to all work for me on a Quest 3! That includes the system-level recentering (ie not using XRServer.center_on_hmd()) when holding the Meta button.

@m4gr3d @BastiaanOlij What do you guys think?

Another question: Since it seems that using LOCAL_FLOOR is the recommended best practice, should we also make it the default reference space?

Copy link
Contributor

@m4gr3d m4gr3d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good!

@BastiaanOlij
Copy link
Contributor

BastiaanOlij commented Jan 18, 2024

I've tested all the different branches (including real LOCAL_FLOOR, emulated LOCAL_FLOOR and where we just fallback on a guessed floor height) by selectively commenting stuff out. It seems to all work for me on a Quest 3! That includes the system-level recentering (ie not using XRServer.center_on_hmd()) when holding the Meta button.

The problem here is that this is another example where OpenXR offers a solution that is ideal when scratch building an game/application, but which clashes with existing logic in game engines that have already provided solutions 5 or more years ago.

Quest also has a one up on the competition, the player is already wearing the headset and already positioned where they want to engage with a game or application, when the game or application starts. So for them these modes make sense.

Other platforms, PCVR, PSVR2, etc. can't make this assumption, the user often is interacting with a computer directly, with a headset set on the floor or on a table or chair. The game starts, and by the time the user has walked to the center of their play space and put the headset on, LOCAL and LOCAL_FLOOR have lost all meaning. They are very likely requiring recalibration.

I've found this experience really annoying with say Elite Dangerous which has attempted to automate this, and do their calibration once the player puts on their headset. It gets it wrong 99% of the time simply because it takes seconds before the user has adjusted the headset to sit comfortably on their head.

It is for this reason that many games, and we have this standard in XR tools, will have a beginning environment that is not susceptible to a tracking mode (usually by being in a LARGE room) and you get the infamous, standard on console games for a few decades, "press any key/button to continue". As this happens when the player is ready, this is where you perform calibration, and that calibration can be heavily customised and often is.

So I'm not so fussed with a fallback, for most of our users neither LOCAL nor LOCAL_FLOOR is relevant especially if they are developing cross platform games as they already have the tools in hand and solutions in place.
For the platform where it does matter, you can be guaranteed LOCAL_FLOOR is supported, you can test for this, and adjust your approach accordingly.

@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 18, 2024

@BastiaanOlij Are you saying that in your opinion we shouldn't be attempting to emulate LOCAL_FLOOR at all?

If we do go that route, and just try LOCAL_FLOOR and fallback on something else if it isn't available, then I think we really need some way to control what that fallback is. Because if I'm building a room scale experience, I'd want LOCAL_FLOOR to fall back on STAGE, if possible, before falling all the way back on LOCAL.

@BastiaanOlij
Copy link
Contributor

BastiaanOlij commented Jan 18, 2024

@BastiaanOlij Are you saying that in your opinion we shouldn't be attempting to emulate LOCAL_FLOOR at all?

If we do go that route, and just try LOCAL_FLOOR and fallback on something else if it isn't available, then I think we really need some way to control what that fallback is. Because if I'm building a room scale experience, I'd want LOCAL_FLOOR to fall back on STAGE, if possible, before falling all the way back on LOCAL.

We already default to STAGE, I'm saying that if you try and set a reference space that isn't supported, it just fails and it stays on whatever is the current reference space.

LOCAL is only the default if STAGE is not supported, which only applies to old 3DOF devices, but those are ancient history by now.

On recenter you simply:

  • call XRServer.center_on_hmd(XRServer.RESET_BUT_KEEP_TILT, false) which is the same as being in local space
  • call XRServer.center_on_hmd(XRServer.RESET_BUT_KEEP_TILT, true) which is the same as being in local_floor space

What you often also do an automatic recenter, but either on the infamous "press a button to continue" approach, or after a given time where you can assume the user is now in the right spot wearing their headset (not a fan). Like I said, in XR tools we've used option 1 for many years, far before OpenXR introduced reference spaces.

That works on all platforms consistently and solves the issue when you can't be guaranteed the user is ready when your game starts.

Now if you do want to use LOCAL_FLOOR when available and leave it up to the XR runtime you simply do something like:

var xr_interface : OpenXRInterface

func _ready():
  xr_interface = XRServer.find_interface('OpenXR')
  
  ...
  
  xr_interface.connect("pose_recentered", _on_openxr_pose_recentered)
  
  ...

func _on_openxr_pose_recentered():
  if xr_interface and xr_interface.xr_play_area_mode == XRInterface.XR_PLAY_AREA_ROOMSCALE:
    XRServer.center_on_hmd(XRServer.RESET_BUT_KEEP_TILT, true)

So we assume the XR runtime takes care of things unless our mode is roomscale, else we fall back on our existing logic.

In writing that I do realise we never fully implemented the play area mode. It's there in the background but ignored in the OpenXR implementation, so that needs to be added.
I think this may have been lost in converting logic to Godot 4. Play area modes are generic options that should shadow the OpenXR values, that we can set and get on the XRInterface, but where implementation details are on the interface implementation (same as the environment blend mode).

(sorry for the edits, this was going down memory lane and verifying a few things in code)

@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 18, 2024

Ok, thanks! I generally agree with that, and exposing the selected reference space to the developer was what I had in mind, so I can try and finish implementing that bit. I'll update this PR a little later. :-)

However, I think we may be a little misaligned on the use case for the different reference space types, and which should be manually recentered using XRServer.center_on_hmd() and which will be handled by the system. (Or, maybe I'm just misunderstanding what you're saying with regard to those bits? The challenges of communicating in text form ;-))

LOCAL is only the default if STAGE is not supported, which only applies to old 3DOF devices, but those are ancient history by now.

I think there are still valid use-cases for LOCAL, where you want the player positioned relative to their head and not the floor. This could be a purely seated experience that doesn't include a "virtual chair", or something like Gorilla Tag or Baby Hands, where the virtual floor is positioned relative to your head and hands and the real world floor isn't taken into account at all.

On recenter you simply:

  • call XRServer.center_on_hmd(XRServer.RESET_BUT_KEEP_TILT, false) which is the same as being in local space
  • call XRServer.center_on_hmd(XRServer.RESET_BUT_KEEP_TILT, true) which is the same as being in local_floor space

Both LOCAL and LOCAL_FLOOR handle recentering at the system-level, ie we don't need to call XRServer.center_on_hmd() because the runtime will recenter the space for you. It's only on STAGE that the runtime does nothing, and we have to handle it all in the game.

Or, are you basically just explaining how you'd do something similar to those spaces while using STAGE? If so, then, yes, I agree with that :-)

@dsnopek dsnopek force-pushed the openxr-local-floor branch from 4bade79 to 698a1cf Compare January 18, 2024 17:20
@dsnopek dsnopek requested review from a team as code owners January 18, 2024 17:20
@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 18, 2024

In my latest push:

  • It no longer guesses an arbitrary floor height if LOCAL_FLOOR is requested, but we can't emulate it properly because STAGE isn't supported either. It just falls back on LOCAL.
  • I did more testing with the emulated LOCAL_FLOOR, and I think I now have it updating the floor height when it changes just like real LOCAL_FLOOR. In both modes, I tried pausing the app, redoing my boundary to put the floor at some arbitrary wrong height, then resuming the app, and the floor immediately moves to the new location.
  • OpenXRInterface::get_play_area_mode() will return a value based on the OpenXR reference space that is actually used. I'm not sure if I've got the mapping right, because they don't line up exactly. This is what I have currently (please let me know if you think the mappings should be different!):
    • XR_REFERENCE_SPACE_TYPE_LOCAL -> XRInterface::XR_PLAY_AREA_SITTING
    • XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT -> XRInterface::XR_PLAY_AREA_ROOMSCALE
    • XR_REFERENCE_SPACE_TYPE_STAGE -> XRInterface::XR_PLAY_AREA_STAGE
  • XRServer::center_on_hmd() had a check that made it do nothing if the play area was STAGE which was also mentioned in the docs, however, I think this is actually reversed. When in STAGE is when you should use XRServer::center_on_hmd(), because the system isn't going to do any re-centering for you. So, I removed that check and updated the docs that mentioned the old behavior. This should now work correctly with a modified version of the code snippet that Bastiaan posted yesterday:
    func _on_openxr_pose_recentered():
      if xr_interface and xr_interface.xr_play_area_mode == XRInterface.XR_PLAY_AREA_STAGE:
        XRServer.center_on_hmd(XRServer.RESET_BUT_KEEP_TILT, true)
    
    The change is necessary because I mapped OpenXR's STAGE to STAGE in OpenXRInterface, and it's STAGE where the game has to do the recentering manually.

Anyway, I'm feeling pretty happy with this implementation now! It should allow LOCAL_FLOOR to work on any OpenXR runtime either directly supports it or at least supports STAGE, and we are now giving the developer enough information to handle the cases where they requested a particular reference space but we couldn't provide it to them.

@m4gr3d @BastiaanOlij Please let me know what you think!

@dsnopek dsnopek requested a review from m4gr3d January 18, 2024 17:38
@BastiaanOlij
Copy link
Contributor

BastiaanOlij commented Jan 19, 2024

Both LOCAL and LOCAL_FLOOR handle recentering at the system-level, ie we don't need to call XRServer.center_on_hmd() because the runtime will recenter the space for you. It's only on STAGE that the runtime does nothing, and we have to handle it all in the game.

Yeah basically that is the point. We have an existing system long before OpenXR and reference spaces were introduced, and that should remain the default behavior as to not break peoples existing games and projects.

Alternatively you can use LOCAL and/or LOCAL_FLOOR and let the system handle it for you.

However I think it is very important to underline that LOCAL_FLOOR has two weaknesses that need to be well documented:

  1. not all platforms support it, and some platforms may opt out of it, as mentioned, I'm not a fan of the fallback mode for reasons I've already mentioned (though if I'm outvoted on this one, I'm happy to keep the solution in place that you added)
  2. this mode promotes the wrong belief that XROrigin3D represents the position of the player, not the center of your playspace. It is still the center of your playspace, the center just happens to be moved to where the player is currently standing. The player can still physically move away from that center. So if I can't move into a room, all I need to do is take two physical steps backwards, use my controller to virtual move forwards, the center of my play space is now in the unreachable room. Hit recenter, voila I'm in the room I'm not supposed to be (center_on_hmd has this problem too, but you can alter your recenter code to only do this on level load, but only recenter your orientation mid game)

This btw is in no means a reason not to implement or use it. It is just a weakness that needs to be clearly documented so developers know what the pitfalls are and don't draw the wrong conclusion. All these issues are solvable.

@@ -690,6 +690,20 @@ bool OpenXRInterface::supports_play_area_mode(XRInterface::PlayAreaMode p_mode)
}

XRInterface::PlayAreaMode OpenXRInterface::get_play_area_mode() const {
if (!openxr_api) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to also implement supports_play_area_mode and set_play_area_mode

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to support changing the reference space mid-game? Right now it takes this value from a project setting that's only used during initialization.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can, forgot that we do this during init. If we need to tear down a session and rebuild it, it will be overkill and it indeed makes more sense that set_play_area_mode gives and error after OpenXR is initialised. But if it can change on the fly that would be cool.

Imagine switching between LOCAL and LOCAL_FLOOR as you enter/exit a vehicle

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can. But, personally, I'd be fine with this only being allowed during init (or like you suggest, giving an error if set when OpenXR is already initialized), at least until we hit a compelling use case that really needs it. I worry that giving developers this power would cause more problems than it would solve. :-)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsnopek @BastiaanOlij I ran into this while working on the XR editor and I'd suggest removing the restriction (if possible) that the api can only be used prior to initialization.

The project setting applies to the entire project, which doesn't provide much granularity. And trying to use this api prior to the XRInterface being initialized is practically impossible since by the time gdscript can get a handle to the XRInterface instance, it's already initialized.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. In a normal project, you'd set it in the "Project Settings" so that it's at the value you want during initialization, however, I can see how that would be an issue in the XR editor.

From a technical perspective, I think we are able to change reference space after OpenXR is initialized, and so we could remove the restriction. However, I don't know what the experience would be in the headset - I can do some experimentation. In the worst case (like if it's really weird in headset), I guess we can recommend in the docs that developers are careful with this function and maybe black out the camera before doing it or re-center on the HMD after doing it, or something like that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also recommend switching the reference space only during transition from one scene to another.

For now for the XR editor, I'm creating an editor override for the reference space project setting in m4gr3d@6dd167a.

Ideally, it should be possible to update the reference space while the editor is being initialized in https://github.com/m4gr3d/godot/blob/6dd167a3bcc88dc789e36fdc6b9d9b967b6d7321/modules/vr_editor/vr_editor.cpp#L44

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m4gr3d Here's PR #87745 to allow changing the reference space even after OpenXR has been initialized

@@ -256,7 +256,7 @@
Player is free to move around, full positional tracking.
</constant>
<constant name="XR_PLAY_AREA_STAGE" value="4" enum="PlayAreaMode">
Same as [constant XR_PLAY_AREA_ROOMSCALE] but origin point is fixed to the center of the physical space, [method XRServer.center_on_hmd] disabled.
Same as [constant XR_PLAY_AREA_ROOMSCALE] but origin point is fixed to the center of the physical space. In this mode, system-level recentering may be disabled, requiring the use of [method XRServer.center_on_hmd].
Copy link
Contributor

@BastiaanOlij BastiaanOlij Jan 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest doing this the other way around. XR_PLAY_AREA_ROOMSCALE is the mode where the center of the playspace is locked in place as this is the default room scale behavior most headsets adhere to.

The new mode could then be called XR_PLAY_AREA_ROOMSCALE_LOCAL which then has a description such as Same as XR_PLAY_AREA_ROOMSCALE but the center of the play space is calibrate to the position of the player at startup, and when the player does a system recenter. It is important to note that the player can walk away from this center`.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, you're saying that XR_REFERENCE_SPACE_TYPE_STAGE should map to XR_PLAY_AREA_ROOMSCALE? We certainly could do that, the terminology can be whatever we want. :-)

However, it feels weird that XR_PLAY_AREA_STAGE would not equal XR_REFERENCE_SPACE_TYPE_STAGE, given that they both contain STAGE (and the project setting for this also calls it "Stage"). And given the original description of this constant (I only changed the end bit about center_on_hmd()), it certainly seems like this value was meant to be meant to be used for XR_REFERENCE_SPACE_TYPE_STAGE.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Owh, XR_PLAY_AREA_STAGE already exists... hmmm weird.. I see your point.. I think I really badly chose these names way back when :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm tempted to rename them to XR_PLAY_AREA_ROOMSCALE_LOCAL and XR_PLAY_AREA_ROOMSCALE_STAGE, just to set them apart as two roomscale variants..

We'll get in trouble with the production team for a breaking rename but I don't think anyone will even have been aware that we had these options seeing it was never implemented.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If totally renaming them is a possibility, I think having just XR_PLAY_AREA_LOCAL and XR_PLAY_AREA_LOCAL_FLOOR would be great. Those do seem to be sort of standard names - they also exist in WebXR.

Do any low-level XR APIs even have a "space type" for "sitting" or "3dof"? Those are the other values on this enum, but they're not really mappable to anything in OpenXR or WebXR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the mobile VR interface exposes itself as 3DOF as it doesn't have positional tracking, so I'd keep that. I'm happy with having that and the 3 suggestions you make, and removing the rest.

We'll have to make a clear statement as to why we're making this breaking change and why we think we can get away with it (this feature having been unimplemented is a strong indicator that nobody is currently using it:P ).

(obviously if we need to keep the old ones and give them the same const value and mark them as deprecated, that could be a way to make any critics happy, but I rather see them removed).

Copy link
Contributor

@m4gr3d m4gr3d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The updated logic looks good!

@m4gr3d
Copy link
Contributor

m4gr3d commented Jan 20, 2024

However I think it is very important to underline that LOCAL_FLOOR has two weaknesses that need to be well documented:

  1. not all platforms support it, and some platforms may opt out of it, as mentioned, I'm not a fan of the fallback mode for reasons I've already mentioned (though if I'm outvoted on this one, I'm happy to keep the solution in place that you added)

IMO, providing a fallback reinforce our intent for those apis to be cross platform; i.e: the developer can select LOCAL_FLOOR as the space and be assured that the engine will do the right thing even on platforms that don't support it. It is reminiscent of the recent updates to the hand tracking apis / extensions.
So with that in mind, I'm in favor of keeping the emulated fallback.

@BastiaanOlij
Copy link
Contributor

So with that in mind, I'm in favor of keeping the emulated fallback.

I see your point, I think what I worry about is that there is no guarantee we can support fallbacks in the future, and its a fair bit of code that at some point will become obsolete as vendors support this extension.

But I guess it does offer the most consistent behaviour and removes platform differences which indeed is exactly what I'm trying to achieve :)

@BastiaanOlij
Copy link
Contributor

@dsnopek this all looks good, I think the only things that should still be added in are:

  • Implement supports_play_area_mode, just return false on 3DOF, and true on any other play area
  • Implement set_play_area_mode, should error if the interface is initialized, but otherwise update the play area.

I'm still not 100% convinced XR_PLAY_AREA_ROOMSCALE should match the new LOCAL_FLOOR setting and XR_PLAY_AREA_STAGE added, in my head stage has always been roomscale with the center of the room as the origin.
But maybe that is just me not yet being used to local floor being the new kid on the block :)

Time will tell which one will be preferred by users. I think people will be caught out in games if they don't realise the effects of recentering in LOCAL_FLOOR when the player has moved some distance from the last origin location.

@dsnopek dsnopek force-pushed the openxr-local-floor branch from 698a1cf to cc71d9c Compare January 23, 2024 15:09
@dsnopek dsnopek force-pushed the openxr-local-floor branch from cc71d9c to a8690cb Compare January 23, 2024 15:19
@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 23, 2024

@BastiaanOlij Thanks! I've implemented supports_play_area_mode and set_play_area_mode in my latest push

@BastiaanOlij
Copy link
Contributor

Yeah looks good to me, happy for this to be merged.

@YuriSizov YuriSizov merged commit ea6e202 into godotengine:master Jan 24, 2024
16 checks passed
@YuriSizov
Copy link
Contributor

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants